/**
 * @file .
 * @author wangxiaowei0303@163.com
 */

#include <math.h>

#include "../string_util.h"
#include "ContraharmonicMeanFilter.h"

/* this->q 呈现给用户的名称. */
#define Q_ARG "q"

void 
ContraharmonicMeanFilter::help(std::string &buf) const
{
    buf.append(
        "逆谐波均值滤波器;适合处理胡椒噪声,盐粒噪声;\n"
        "但不适合处理椒盐噪声.\n"
        "q;滤波器阶数;double 类型;默认值为 -1.5;\n"
        "  当用于处理盐粒噪声时,q < 0;\n"
        "  当用于处理胡椒噪声时,q > 0\n"
    );
    Filter::help(buf);
}

void
ContraharmonicMeanFilter::set(const char *argname,const char *argval)
{
    if (strEqual(argname,Q_ARG)) 
        this->q = str2double(argval);
    else 
        Filter::set(argname,argval);
    return ;
}

const char*
ContraharmonicMeanFilter::get(const char *argname,std::string &buf) const
{
    size_t oldSize = buf.size();
    if (strEqual(argname,Q_ARG)) 
        addFormat(buf,"%f",this->q);
    else 
       return Filter::get(argname,buf);
    return buf.data() + oldSize;
}

void
ContraharmonicMeanFilter::getSupportedArgs(
    std::vector<std::string> &args) const
{
    args.push_back(Q_ARG);
    Filter::getSupportedArgs(args);
    return ;
}

double
ContraharmonicMeanFilter::operOnNeigh(const cv::Mat &neigh)
{
    double denominator = 0; /* 分母,参见公式 5-3.6 */
    double numerator = 0; /* 分子 */
 
    cv::MatConstIterator_<uchar> iter = neigh.begin<uchar>();
    cv::MatConstIterator_<uchar> const end = neigh.end<uchar>();
    for (; iter != end; ++iter) {
        double gq = ::pow(*iter,this->q);
        denominator += gq;
        numerator += gq * *iter;
    }
    return numerator / denominator;
}

NOISE_ALGO_REGISTER("Contraharmonic",ContraharmonicMeanFilter);
